package org.kabeja.dxf.entity;

import org.kabeja.dxf.DXFConstants;
import org.kabeja.dxf.helpers.DXFSplineConverter;
import org.kabeja.dxf.helpers.SplinePoint;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * @author shutao
 * @since 2022/4/25 9:23
 */
public class DXFSpline extends DXFEntity {
    protected static final int APPROXIMATION_STEPS = 10;
    protected int degree;
    protected int nodePointsSize;
    protected int controlPointSize;
    protected int fitPointSize;
    protected double[] knots;
    protected double[] weights;
    protected List<SplinePoint> points = new ArrayList<>();
    protected double fitTolerance;
    protected double knotsTolerance;
    protected double controlPointTolerance;
    DXFPolyline polyline;

    public DXFSpline() {
        this.setLineType(this.getType());
    }

    @Override
    public Bounds getBounds() {
        if (this.polyline == null) {
            this.polyline = this.toDXFPolyline();
        }

        return this.polyline.getBounds();
    }

    @Override
    public String getType() {
        return DXFConstants.ENTITY_TYPE_SPLINE;
    }

    public void addSplinePoint(SplinePoint var1) {
        this.points.add(var1);
        this.polyline = null;
    }

    public Iterator<SplinePoint> getSplinePointIterator() {
        return this.points.iterator();
    }

    public boolean isRational() {
        return (this.flags & 4) == 4;
    }

    public boolean isClosed() {
        return (this.flags & 1) == 1;
    }

    public boolean isPeriodic() {
        return (this.flags & 2) == 2;
    }

    public boolean isPlanar() {
        return (this.flags & 8) == 8;
    }

    public boolean isLinear() {
        return (this.flags & 16) == 16;
    }

    public int getControlPointSize() {
        return this.controlPointSize;
    }

    public void setControlPointSize(int var1) {
        this.controlPointSize = var1;
    }

    public int getDegree() {
        return this.degree;
    }

    public void setDegree(int var1) {
        this.degree = var1;
    }

    public int getFitPointSize() {
        return this.fitPointSize;
    }

    public void setFitPointSize(int var1) {
        this.fitPointSize = var1;
    }

    public double getFitTolerance() {
        return this.fitTolerance;
    }

    public void setFitTolerance(double var1) {
        this.fitTolerance = var1;
    }

    public double[] getKnots() {
        return this.knots;
    }

    public void setKnots(double[] var1) {
        this.knots = var1;
        this.polyline = null;
    }

    public int getNodePointsSize() {
        return this.nodePointsSize;
    }

    public void setNodePointsSize(int var1) {
        this.nodePointsSize = var1;
    }

    public double[] getWeights() {
        return this.weights;
    }

    public void setWeights(double[] var1) {
        this.weights = var1;
    }

    public double getControlPointTolerance() {
        return this.controlPointTolerance;
    }

    public void setControlPointTolerance(double var1) {
        this.controlPointTolerance = var1;
    }

    public double getKnotsTolerance() {
        return this.knotsTolerance;
    }

    public void setKnotsTolerance(double var1) {
        this.knotsTolerance = var1;
    }

    @Override
    public double getLength() {
        if (this.polyline == null) {
            this.polyline = this.toDXFPolyline();
        }

        return this.polyline.getLength();
    }

    protected DXFPolyline toDXFPolyline() {
        return DXFSplineConverter.toDXFPolyline(this);
    }
}
